package com.ydx.meituan.config.aspect;


import com.ydx.meituan.exception.RequestError;
import com.ydx.meituan.exception.RequestException;
import com.ydx.meituan.model.base.BaseRequest;
import com.ydx.meituan.utils.SignUtil;
import org.apache.commons.lang.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import static com.ydx.meituan.utils.SignUtil.SING_KEY;

@Aspect
@Component
@Order(1)
public class AuthSignAspect {


    private static final Logger logger = LoggerFactory.getLogger(AuthSignAspect.class);

    private static final String point = "@annotation(com.ydx.meituan.config.annotation.AuthSign)";;


    @Pointcut(point)
    public void authSignPoint() {

    }

    @Before(value = "authSignPoint()")
    public void authBefore(JoinPoint joinPoint) throws Exception {
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        String apiName = signature.getName();
        logger.info("api name: "+apiName);

        Object[] args = joinPoint.getArgs(); // 参数值
        String[] parameterNames = signature.getParameterNames(); // 参数名
        Map<String, Object> paramMap = new HashMap();
        for (int i = 0; i < parameterNames.length; i++) {
            paramMap.put(parameterNames[i], args[i]);
        }

        String sign=null;
        TreeMap<String, Object> requestParamMap = new TreeMap<>();

        Iterator<Map.Entry<String, Object>> iterator = paramMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Object> next = iterator.next();
            Object obj = next.getValue();
            if (obj==null)
                continue;

            if (!(obj instanceof BaseRequest))
                continue;

            Class<?> params = obj.getClass();
            Class<?> baseParams = params.getSuperclass();
            Field[] p = params.getDeclaredFields();
            Field[] bp = baseParams.getDeclaredFields();
            Field[] allField = (Field[])ArrayUtils.addAll(p, bp);

            //父类
            for (Field f: allField){
                String name = f.getName();
                f.setAccessible(true);
                Object value = f.get(obj);
                if ("sign".equals(name)){
                    sign=value.toString();
                }else {
                    requestParamMap.put(name,value);
                }
                logger.info(name+"======"+value);
            }
        }

        try {
            String authSign = SignUtil.sign(requestParamMap, SING_KEY);
            if (authSign.equals(sign)){
                logger.info("校验通过");
            }else {
                throw new RequestException(RequestError.REQUEST_ERROR_AUTH_ERROR.getResult(), RequestError.REQUEST_ERROR_AUTH_ERROR.getMessage());
            }
        }catch (Exception e){
            throw new RequestException(RequestError.REQUEST_ERROR_AUTH_ERROR.getResult(), RequestError.REQUEST_ERROR_AUTH_ERROR.getMessage());
        }


    }



}
